package com.ls.controller;


import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.ls.client.ProductFeignClient;
import com.ls.client.UserScoreFeignClient;
import com.ls.entity.Result;
import com.ls.pojo.Order;
import com.ls.pojo.Product;
import com.ls.service.IOrderService;
import com.ls.util.JwtUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.*;

@RestController
@RequestMapping("/order")
@Slf4j
public class OrderController {
    @Autowired
    private IOrderService orderService;

    @Autowired
    private RestTemplate restTemplate;


    @Autowired
    private DiscoveryClient discoveryClient;


    @Autowired
    private ProductFeignClient productFeignClient;


    @Autowired
    private StringRedisTemplate stringRedisTempalte;

    @Autowired
    private UserScoreFeignClient userScoreFeignClient;


    @GetMapping("/{id}")
    public Result findById(@PathVariable Integer id){
        Order order = orderService.getById(id);
        return new Result(200, "查询订单信息成功", order);
    }

    @GetMapping("/buy/{productId}/{number}")
    public Result buy(@PathVariable Integer productId,@PathVariable Integer number,
                      HttpServletRequest request,HttpServletResponse httpResponse)
            throws Exception {
        //1.判断请求头里面是否存在token
        String token = request.getHeader("token");
        String Logintoken = request.getHeader("Logintoken");
        if (StringUtils.isEmpty(token)){
            return new Result(500,"非法的请求");
        }

        //2.删除redis中的token(成功：第一次请求 失败:不是第一次请求)
        Boolean flag = stringRedisTempalte.delete("idempotent:" + token);
        if (!flag){
            //表示redis中不存在token，不是第一次请求
            return new Result<>(500,"重复的请求");
        }
        //3.处理本地业务逻辑
        //查询商品
        Result<Product> result = productFeignClient.findById(productId);
        Product product = result.getData();
        System.out.println("product = " + product);
        //4、判断商品库存是否足够
        if (product.getStock()<number){
            return new Result<>(500,"库存不足，只剩下"+product.getStock()+"件，请重新下单");
        }
        //5、拿到当前登录用户存储再token的用户id
        Claims claims = JwtUtil.parseJWT(Logintoken);
        Integer userId = (Integer) claims.get("userId");
        //6、下单操作，添加订单信息
        log.debug("往订单里面添加一条记录===========");
        Order order =  orderService.saveOrder(product,number,userId);
        //7、跳转到支付界面
        AlipayClient alipayClient = new DefaultAlipayClient(
                "https://openapi.alipaydev.com/gateway.do",
                "2021000122610709",
                "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCVQHuyfvAqBMTFR7yTYBNqoEdyLABCm7dUBk8I4SdnbCH7xqo0IZ2bOpGhj2ZbxPgR9zov5+x9hEE50nTcNTiijqWchVYWxvFdmyBLVidw1YywbA6sd8MRaMpZavUZ9+r10wJFKucmUqjKTCOqKerwO7w8895AZx+cumxCRorJ510CISiJR7SVWHlWSg/MOFT18G9x5U8Vl2mrnHqS+3JwV4/eZl6qmIDeB1Xskn5eLY4wBi4GhIp8dJmIntYK7KhjjG5pEB5zOWvb6dGor1W9rryRT6uY7CNp2f3Bm9iJIXFBj07KvqyQ6k/s6gQB7x2N7zWX6O0G8uM3JzprgqzTAgMBAAECggEAPdbz6acytxY2uU7Z0W5TXTB/qcyVZwPB1+ytPo6blvx0sC9GQkdTWAfSY1BZJtjbuAXpdAPyNqdfpyeOB9d9Wc0kzU9pthJD23b00IIn4VZ57nc3NTqB9mqmvJnWaCYSkjwVircWAwjoqrkVZeHsWBFIEzEv+xs/O976EBPOWY0DMfv7CVHJReaueC/5V8lxIIESUbhZ9vaVeelOw2UNZY+sNN+W871AkmezkheXP+TCfpcfLFUHWM/c/x3I/efJHkztvC9M9lkr/PC+WBm14KBw4+8a4BJUS61ByjMRRzxptHCNwkZ4EDKj2tX6qkFDTjVQsl07Fk9A2mtJ5ApBUQKBgQDIfKshy/8ovyjE9PuuHo5KIQ+BPm7LaMGSZBKkkloIU7RAyczU0sri2wqNXT36QcmZoUOOK1aYYpCg7/PW8hehcKN6jRxwwrdvSqMIbaEJByND+dl0HMl6oB/KQDAcOsEcfKZpOUk/lqCFnhFFMDjD53Sw0LqoX6PUKzZYzAZI3wKBgQC+lBAaaYUV3HwHINqrmAeYInKs0mORUGagpo/1JR4UPQ8lLbeTp3S62Eb/o3TvSjpWdgte8S6NVtuGkYOukYSxg5/2gd6pqGE7R5BUNL0glpT1u0StCY768OTuvrYzVmlfc8Dr4H+au8ahqSDCSVAZ9jGFU+/mTi0SApGGzYK2jQKBgQCRSa8mpdO6LpWX7cU50FDjLYQz8A+QftDQio7sDlcKc8ZLsTIsBLocngnOmgShB+3V1ITFUWjGs58F0f4OBZDUYHFIDVzP5nvSPe9Z20B472BCEZzhRT9JCyMeiVeUDYwGXdqmpGoNl9WqHvt6/VAVv/TTcd/ixrRNvCb9QJVJVwKBgQCPHiH5s8R95lY+BC4zLriFR1lW76hWOErZ2jvBnV45VKFLCkoSWG8Q4dpvoBDwoo2s4Hkpk3WiLtgs9potPpqntHEsbdsJDan3GocItZJSJsM2xquMRuFZEg7aO94YL4xyYjs+6Bjr2pgQTzKKtQOye3A08BP4oDy4ibU/xpWjAQKBgE/33rFzQ0CWecNSepFarqadN4Ts9koKsURjRXt3Cr9dT+yr/EO+yC9ThWG3W/zgP5SWOTjSn9o66VmvLNmuaxA5khTwe13n5gYAuAkVx3lL5FSTK4f4XggPnEDR3C9A1UIjnKTOkT5g2YWD3KMt+fO52R36tf6GC+fRRz+4w5Js",
                "json",
                "UTF-8",
                "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjxxGuV2svDly0AHU/+1yJEvOMkZ67Ems3GhUMOeJqe4USVaD4reeSRUH8h48MZGuDlBDucpE188KZwPM7cYJIH+xMWY2C6jwQnpcoFj/MYSPPguUR9krr12sokLLYSiM0fLg5E8HmBjC4Mkx1AL3E2sMeAhrbkZdJ9FVXKs7m6bkpmgFvqKPYbw7Ce5P1T5wth7aKfTi+Dpj5IzarImydnUUg2U/kwpyKhk08tuWe/efe4H3gm1IOEX/u8/brnh9eqPJr3Pw0syfkmF80ssu1q+tWXVLJ3Sj//+/KwjE2IfK9ge4tQnZOPV8Oq2ogdqT/Ivkip8C7387SzFM0nC9qQIDAQAB", "RSA2");  //获得初始化的AlipayClient
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest(); //创建API对应的request
        alipayRequest.setReturnUrl("http://t9i8iy.natappfree.cc/order/return_url");
        alipayRequest.setNotifyUrl("http://t9i8iy.natappfree.cc/order/notify_url"); //在公共参数中设置回跳和通知地址
        alipayRequest.setBizContent("{" +
                "    \"out_trade_no\":"+order.getId()+"," +
                "    \"product_code\":\"FAST_INSTANT_TRADE_PAY\"," +
                "    \"total_amount\":"+order.getPrice()+"," +
                "    \"subject\":\"Iphone6 16G\"," +
                "    \"body\":\"Iphone6 16G\"," +
                "    \"passback_params\":\"merchantBizType%3d3C%26merchantBizNo%3d2016010101111\"," +
                "    \"extend_params\":{" +
                "    \"sys_service_provider_id\":\"2088511833207846\"" +
                "    }" +
                "  }"); //填充业务参数
        String form = "";
        try {
            form = alipayClient.pageExecute(alipayRequest).getBody();  //调用SDK生成表单
            System.out.println(form);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        httpResponse.setContentType("text/html;charset=" + "UTF-8");
        try {
            httpResponse.getWriter().write(form); //直接将完整的表单html输出到页面

            httpResponse.getWriter().flush();
            httpResponse.getWriter().close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        //这个要放到异步回调里面，该方法本身非幂等，此处需要进行幂等性校验
        String stockToken =createToken().getData();
        Result result2 = productFeignClient.updateStockById(productId,stockToken);
        String message = result2.getMessage();

        //响应数据
        return new Result(200, result2.getMessage());
    }

    @GetMapping("/return_url")
    public String return_url(){
        System.out.println("支付宝沙箱支付的同步回调回来了。。。。。。。。。。。。。。。。。。。");
        // 同步回调，跳转页面
        return "order";
    }

    @PostMapping("/notify_url")
    @ResponseBody
    public String notify_url(HttpServletRequest request) throws UnsupportedEncodingException {
        System.out.println("支付宝沙箱支付的异步回调回来了。。。。。。。。。。。。。。。。。。。");
        //获取支付宝POST过来反馈信息
        Map<String,String> params = new HashMap<>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。
            valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
        //切记alipaypublickey是支付宝的公钥，请去open.alipay.com对应应用下查看。

        try {
            boolean flag = AlipaySignature.rsaCheckV1(params, "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjxxGuV2svDly0AHU/+1yJEvOMkZ67Ems3GhUMOeJqe4USVaD4reeSRUH8h48MZGuDlBDucpE188KZwPM7cYJIH+xMWY2C6jwQnpcoFj/MYSPPguUR9krr12sokLLYSiM0fLg5E8HmBjC4Mkx1AL3E2sMeAhrbkZdJ9FVXKs7m6bkpmgFvqKPYbw7Ce5P1T5wth7aKfTi+Dpj5IzarImydnUUg2U/kwpyKhk08tuWe/efe4H3gm1IOEX/u8/brnh9eqPJr3Pw0syfkmF80ssu1q+tWXVLJ3Sj//+/KwjE2IfK9ge4tQnZOPV8Oq2ogdqT/Ivkip8C7387SzFM0nC9qQIDAQAB", "UTF-8","RSA2");
            //如果验签失败
            if(!flag){
                System.out.println("验证失败");
                return "fail";
            }

            //2.订单的支付状态（在支付宝那边的状态）
            if (params.get("trade_status").equals("TRADE_SUCCESS")) { // 表示支付成功
                //商户的业务逻辑处理：1、给用户添加购买金额等同的积分
                // 根据订单编号去查询该回调的订单的状态
                String serial = params.get("trade_no");
                String out_trade_no = params.get("out_trade_no");
                Order order = orderService.getById(out_trade_no);
                if (order == null) {
                    System.out.println("该订单不存在");
                    return "fail";
                }
                //1、给用户添加购买金额等同的积分
                BigDecimal amount = order.getAmount();
                Integer addscore = amount.intValue();
                Integer userId = order.getUserId();
                Integer action=2;
                userScoreFeignClient.addBuyscore(userId,addscore,action);
            }

            System.out.println("本地业务处理成功");
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return "success";
    }












    @GetMapping("/finduser/{userId}")
    public Result finduser(@PathVariable Integer userId){
        //1、根据用户ID，查询出用户的信息，需要调用mall-user工程，查询商品的信息
        List<ServiceInstance> instances = discoveryClient.getInstances("mall-user");
        //判断一下里面是否有可用服务,没有直接返回,这里存在一个缓存的问题,多访问一次就好了
        if (instances.size() == 0){
            return new Result(500,"没有可用服务");
        }
        ServiceInstance instance = instances.get(0);
        String ip = instance.getHost();
        int port = instance.getPort();
        String url ="http://"+ip+":"+port+"/user/"+userId;
        Result result = restTemplate.getForObject(url, Result.class);
        Object data = result.getData();

        return new Result(200, "查询用户成功", data);
    }

    @GetMapping("/create/token")
    public Result<String> createToken(){
        //1、生成token
        String token = UUID.randomUUID().toString().replaceAll("-", "");
        //2、将生成的token存储到redis中
        stringRedisTempalte.opsForValue().set("idempotent:"+token,token);
        //3、将token返回
        return new Result<>(200,"获取token成功",token);

    }

}
